<?php
/**
 * Created by PhpStorm.
 * User: zhengze
 * Date: 2019/7/1
 * Time: 18:29
 */

namespace app\api\service;

use app\api\model\Member as MemberModel;
use app\api\validate\MemberValidate;
use common\cache\TheRedis;
use common\exception\MemberException;
use common\exception\SystemException;
use common\exception\ExceptionEmun;
use common\service\BaseService;
use common\token\Token;
use common\traits\InstanceTrait;

/**
 * Class MemberService
 * @package app\api\service
 */
class MemberService extends BaseService
{
    use InstanceTrait;

    private $login_max_times = 5;
    private $register_max_times = 10;

    /**
     * 注册
     * @param $post
     * @return string token
     * @throws \ReflectionException
     * @throws \common\exception\BaseException
     */
    public function register($post)
    {
        MemberValidate::instance()->runCheck($post, '', __FUNCTION__);
        $register_error = $this->getRegisterTimes($_SERVER['REMOTE_ADDR']);
        if ($register_error >= $this->register_max_times) {
            ExceptionEmun::throwException(MemberException::FREQUENT_REGISTER);
        }
        $post['password'] = encrypt_password($post['password']);
        if (MemberModel::instance()->save($post)) {
            $this->incRegisterTimes($_SERVER['REMOTE_ADDR']);
            $res = MemberModel::instance()->getByPhone($post['phone']);
        } else {
            ExceptionEmun::throwException(SystemException::UPDATE_FAILE);
        }
        $token = Token::instance()->generateToken($res);
        return $token;
    }

    /**
     * 登录验证
     * @param $post
     * @return string token
     * @throws \ReflectionException
     * @throws \common\exception\BaseException
     */
    public function loginVerify($post)
    {
//      错误次数过多
        $login_error = $this->getLoginTimes($_SERVER['REMOTE_ADDR']);
        if ($login_error >= $this->login_max_times) {
            //返回captcha,提示前端使用验证码
            $ret_data = ['captcha' => 1];
            BaseException::instance()->addData($ret_data);
            MemberValidate::instance()->addRetDat($ret_data);
            //超过次数,验证验证码
            if ($login_error >= $this->login_max_times + 1) {
                $rules = ['captcha|验证码' => ['require', 'captcha']];
                MemberValidate::instance()->addRule($rules);
            }
        }

        MemberValidate::instance()->runCheck($post, '', __FUNCTION__);
        $member_info = MemberModel::instance()->getByPhone($post['phone']);
        if (empty($member_info)) {
            ExceptionEmun::throwException(MemberException::NO_EXIST);
        }
        if (password_verify($post['password'], $member_info['password']) == false) {
            $this->incLoginTimes($_SERVER['REMOTE_ADDR']);
            ExceptionEmun::throwException(MemberException::INCORRECT_PASSWORD);
        }
        $token = Token::instance()->generateToken($member_info);

        return $token;
    }

    /**
     * 登陆失败次数+1
     * @param $mark
     * @return bool
     */
    private function incLoginTimes($mark)
    {

        $key = TheRedis::instance()->generate_cache_key('member', $mark, 'login_times');
        $login_times = cache($key);
        if (!empty($login_times)) {
            $login_times++;
        } else {
            $login_times = 1;
        }
        cache($key, $login_times, [
            'expire' => 60 * 15,
        ]);
        return true;
    }

    /**
     * 获取登陆失败次数
     * @param type $mark 唯一标识
     * @return integer
     */
    private function getLoginTimes($mark)
    {
        $key = TheRedis::instance()->generate_cache_key('member', $mark, 'login_times');
        $login_times = cache($key);
        return $login_times ? $login_times : 0;
    }

    /**
     * 注册成功次数+1
     * @param $mark 唯一标识
     * @return bool
     */
    private function incRegisterTimes($mark)
    {
        $key = TheRedis::instance()->generate_cache_key('member', $mark, 'register_times');
        $register_error = cache($key);
        if (!empty($register_error)) {
            $register_error++;
        } else {
            $register_error = 1;
        }
        cache($key, $register_error, [
            'expire' => 60 * 15,
        ]);
        return true;
    }

    /**
     * 获取注册成功次数
     * @param type $mark 唯一标识
     * @return integer
     */
    private function getRegisterTimes($mark)
    {
        $key = TheRedis::instance()->generate_cache_key('admin', $mark, 'register_times');
        $login_times = cache($key);
        return $login_times ? $login_times : 0;
    }
}